import React, { useRef, useEffect } from 'react'
import * as THREE from 'three'
import { useMount } from 'ahooks'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { IFCLoader } from 'web-ifc-three/IFCLoader'
// import { IFCLoader } from 'three/examples/jsm/loaders/IFCLoader.js'
import store from '@/store'
import { useAsyncEffect } from 'ahooks'

import styles from './index.module.scss'

const IFCViewer = () => {
  const [ifcState, ifcDispatchers] = store.useModel('ifc')
  const { ifcId } = ifcState

  const IFCViewerRef = useRef()

  const { current } = useRef({})

  useMount(() => {
    current.scene = null
    current.renderer = null
    current.camera = null
    init()
  })

  useAsyncEffect(async () => {
    const isSuccess = await ifcDispatchers.getData()
    if (isSuccess) {
      createIFC(`./${ifcId}.ifc`)
    }
  }, [ifcId])

  const render = () => {
    current.renderer.render(current.scene, current.camera)
  }

  const createIFC = async path => {
    const ifcLoader = new IFCLoader()
    await ifcLoader.ifcManager.setWasmPath('ifc/')
    ifcLoader.load(path, function (model) {
      current.scene.add(model.mesh)
      render()
    })
  }

  const init = async () => {
    //Scene
    current.scene = new THREE.Scene()
    current.scene.background = new THREE.Color(0x8cc7de)

    //Camera
    current.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
    current.camera.position.z = -70
    current.camera.position.y = 25
    current.camera.position.x = 90

    //Lights
    const directionalLight1 = new THREE.DirectionalLight(0xffeeff, 0.8)
    directionalLight1.position.set(1, 1, 1)
    current.scene.add(directionalLight1)

    const directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.8)
    directionalLight2.position.set(-1, 0.5, -1)
    current.scene.add(directionalLight2)

    const ambientLight = new THREE.AmbientLight(0xffffee, 0.25)
    current.scene.add(ambientLight)

    //Renderer
    current.renderer = new THREE.WebGLRenderer({ antialias: true })
    current.renderer.setSize(window.innerWidth, window.innerHeight)
    current.renderer.setPixelRatio(window.devicePixelRatio)
    IFCViewerRef.current.appendChild(current.renderer.domElement)
    //Controls
    const controls = new OrbitControls(current.camera, current.renderer.domElement)

    controls.addEventListener('change', render)
    window.addEventListener('resize', onWindowResize)

    render()
  }

  const onWindowResize = () => {
    current.camera.aspect = window.innerWidth / window.innerHeight
    current.camera.updateProjectionMatrix()
    current.renderer.setSize(window.innerWidth, window.innerHeight)

    render()
  }

  return <div ref={IFCViewerRef} className={styles.background}></div>
}

export default IFCViewer
